package xin.codedream.codelog.service.impl;

import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xin.codedream.codelog.dao.CategoryDao;
import xin.codedream.codelog.exception.CategoryException;
import xin.codedream.codelog.model.entity.Category;
import xin.codedream.codelog.service.ArticleService;
import xin.codedream.codelog.service.CategoryService;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 分类目录服务实现
 *
 * @author NGLSL
 * @date 2018/8/12
 */
@Log4j2
@Service
public class CategoryServiceImpl implements CategoryService {
    @Resource
    private CategoryDao categoryDao;
    @Resource
    private ArticleService articleService;

    @Override
    public List<Category> findAllCategory() {
        List<Category> categories = categoryDao.listAllCategory();
        if (!categories.isEmpty()) {
            // 筛选出父级目录
            List<Category> parent = categories.stream().filter(cate -> cate.getCateParentId() == 0).collect(Collectors.toList());
            // 筛选出子集目录
            List<Category> child = categories.stream().filter(cate -> cate.getCateParentId() != 0).collect(Collectors.toList());
            // 递归将子目录添加到对应的父级目录
            parent.forEach(cate -> buildChildren(cate, child, 1));
            return parent;
        }
        return categories;
    }

    @Override
    public Category findCategoryByCateId(Long cateId) {
        return categoryDao.selectCategoryByCateId(cateId);
    }

    @Override
    public boolean removeCategoryByCateId(Long cateId) {
        return categoryDao.deleteCategoryByCateId(cateId) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeCategory(Long cateId) throws CategoryException {
        Category category = this.findCategoryByCateId(cateId);
        if (category != null) {
            articleService.updateArticleCateByCateId(category.getCateId(), category.getCateParentId());
            boolean categoryUpdateResult = this.removeCategoryByCateId(cateId);
            if (categoryUpdateResult) {
                return true;
            } else {
                throw new CategoryException(String.format("目录删除失败-ID:%s", category.getCateId()));
            }
        }
        return false;
    }

    @Override
    public boolean saveCategoryInfo(Category category) {
        return categoryDao.insertCategoryInfo(category) > 0;
    }

    @Override
    public boolean updateCategoryInfo(Category category) {
        return categoryDao.updateCategoryInfo(category) > 0;
    }

    /**
     * 递归添加子目录
     *
     * @param category   当前目录
     * @param categories 目录集合
     * @param index      目录等级
     */
    private void buildChildren(Category category, List<Category> categories, long index) {
        List<Category> children = category.getChildren();
        if (Objects.isNull(children)) {
            children = new ArrayList<>();
        }
        category.setChildren(children);
        category.setIndex(index);
        for (Category cate : categories) {
            if (category.getCateId().equals(cate.getCateParentId())) {
                cate.setIndex(index + 1);
                children.add(cate);
                buildChildren(cate, categories, cate.getIndex());
            }
        }
    }
}
